﻿using System;

namespace pri.smilly.QuickStart.Aop {
    public class ExpressionMatcher : IMatcher {
        private string _expression;

        public ExpressionMatcher(string expression) {
            _expression = expression;
        }

        public bool IsMatch(string metodSinature) {
            // compare body expression
            if (!Match(BodyItems(_expression), BodyItems(metodSinature))) return false;
            // compare args expression
            string[] argsItems = ArgsItems(_expression);
            if (argsItems.Length == 0) return true;
            if (argsItems.Length == 1 && argsItems[0].Equals("..")) return true;
            return Match(argsItems, ArgsItems(metodSinature));
        }

        private string[] BodyItems(string expression) {
            int end = expression.IndexOf('(');
            if (end < 0) end = expression.Length;
            return expression.Substring(0, end).Split('.');
        }

        private string[] ArgsItems(string expression) {
            int start = expression.IndexOf('(') + 1;
            if (start == 0) return new string[0];

            int length = expression.IndexOf(')') - start;
            return expression.Substring(start, length).Split(',');
        }

        private bool Match(string[] expressionItems, string[] inputItems) {
            if (inputItems.Length < expressionItems.Length) return false;
            for (int i = 0; i < expressionItems.Length; i++) {
                if (expressionItems[i].Equals("**")) break;
                if (expressionItems[i].Equals("*")) continue;
                if (expressionItems[i].Equals(inputItems[i])) continue;
                return false;
            }

            return true;
        }
    }
}